#ifndef ELFHEADER_H
#define ELFHEADER_H

#include <QObject>

class ELFHelper : public QObject {
  Q_OBJECT
public:
  typedef enum {
    ELFCLASSNONE = 0,
    ELFCLASS32 = 1,
    ELFCLASS64 = 2
  } ei_class_2_e;

  typedef enum { ELFDATAONE = 0, ELFDATA2LSB = 1, ELFDATA2MSB = 2 } ei_data_e;

  typedef enum { E_NONE = 0, E_CURRENT = 1 } ei_version_e;

  typedef enum {
    ELFOSABI_NONE = 0,     // No extensions or unspecified
    ELFOSABI_HPUX = 1,     // Hewlett-Packard HP-UX
    ELFOSABI_NETBSD = 2,   // NetBSD
    ELFOSABI_SOLARIS = 6,  // Sun Solaris
    ELFOSABI_AIX = 7,      // AIX
    ELFOSABI_IRIX = 8,     // IRIX
    ELFOSABI_FREEBSD = 9,  // FreeBSD
    ELFOSABI_TRU64 = 10,   // Compaq TRU64 UNIX
    ELFOSABI_MODESTO = 11, // Novell Modesto
    ELFOSABI_OPENBSD = 12, // Open BSD
    ELFOSABI_OPENVMS = 13, // Open VMS
    ELFOSABI_NSK = 14,     // Hewlett-Packard Non-Stop Kernel
    ELFOSABI_AROS = 15     // Amiga Research OS
  } ei_osabi_e;

  typedef enum {
    ET_NONE = 0,
    ET_REL = 1,
    ET_EXEC = 2,
    ET_DYN = 3,
    ET_CORE = 4,
    ET_LOOS = 0xfe00,
    ET_HIOS = 0xfeff,
    ET_LOPROC = 0xff00,
    ET_HIPROC = 0xffff
  } e_type_e;

  typedef enum {         // list has to to be completed
    EM_NONE = 0,         // No machine
    EM_M32 = 1,          // AT&T WE 32100
    EM_SPARC = 2,        // SPARC
    EM_386 = 3,          // Intel 80386
    EM_68K = 4,          // Motorola 68000
    EM_88K = 5,          // Motorola 88000
    reserved6 = 6,       // Reserved for future use (was EM_486)
    EM_860 = 7,          // Intel 80860
    EM_MIPS = 8,         // MIPS I Architecture
    EM_S370 = 9,         // IBM System/370 Processor
    EM_MIPS_RS3_LE = 10, // MIPS RS3000 Little-endian
    reserved11 = 11,     // Reserved for future use
    reserved12 = 12,     // Reserved for future use
    reserved13 = 13,     // Reserved for future use
    reserved14 = 14,     // Reserved for future use
    EM_PARISC = 15,      // Hewlett-Packard PA-RISC
    reserved16 = 16,     // Reserved for future use
    EM_VPP500 = 17,      // Fujitsu VPP500
    EM_SPARC32PLUS = 18, // Enhanced instruction set SPARC
    EM_960 = 19,         // Intel 80960
    EM_PPC = 20,         // PowerPC
    EM_PPC64 = 21,       // 64-bit PowerPC
    EM_S390 = 22,        // IBM System/390 Processor
    reserved23 = 23,     // Reserved for future use
    reserved24 = 24,     // Reserved for future use
    reserved25 = 25,     // Reserved for future use
    reserved26 = 26,     // Reserved for future use
    reserved27 = 27,     // Reserved for future use
    reserved28 = 28,     // Reserved for future use
    reserved29 = 29,     // Reserved for future use
    reserved30 = 30,     // Reserved for future use
    reserved31 = 31,     // Reserved for future use
    reserved32 = 32,     // Reserved for future use
    reserved33 = 33,     // Reserved for future use
    reserved34 = 34,     // Reserved for future use
    reserved35 = 35,     // Reserved for future use
    EM_V800 = 36,        // NEC V800
    EM_FR20 = 37,        // Fujitsu FR20
    EM_RH32 = 38,        // TRW RH-32
    EM_RCE = 39,         // Motorola RCE
    EM_ARM = 40,         // Advanced RISC Machines ARM
    EM_ALPHA = 41,       // Digital Alpha
    EM_SH = 42,          // Hitachi SH
    EM_SPARCV9 = 43,     // SPARC Version 9
    EM_TRICORE = 44,     // Siemens TriCore embedded processor
    EM_ARC = 45,         // Argonaut RISC Core, Argonaut Technologies Inc.
    EM_H8_300 = 46,      // Hitachi H8/300
    EM_H8_300H = 47,     // Hitachi H8/300H
    EM_H8S = 48,         // Hitachi H8S
    EM_H8_500 = 49,      // Hitachi H8/500
    EM_IA_64 = 50,       // Intel IA-64 processor architecture
    EM_MIPS_X = 51,      // Stanford MIPS-X
    EM_COLDFIRE = 52,    // Motorola ColdFire
    EM_68HC12 = 53,      // Motorola M68HC12
    EM_MMA = 54,         // Fujitsu MMA Multimedia Accelerator
    EM_PCP = 55,         // Siemens PCP
    EM_NCPU = 56,        // Sony nCPU embedded RISC processor
    EM_NDR1 = 57,        // Denso NDR1 microprocessor
    EM_STARCORE = 58,    // Motorola Star*Core processor
    EM_ME16 = 59,        // Toyota ME16 processor
    EM_ST100 = 60,       // STMicroelectronics ST100 processor
    EM_TINYJ = 61,       // Advanced Logic Corp. TinyJ embedded processor family
    EM_X86_64 = 62,      // AMD x86-64 architecture
    EM_PDSP = 63,        // Sony DSP Processor
    EM_PDP10 = 64,       // Digital Equipment Corp. PDP-10
    EM_PDP11 = 65,       // Digital Equipment Corp. PDP-11
    EM_FX66 = 66,        // Siemens FX66 microcontroller
    EM_ST9PLUS = 67,     // STMicroelectronics ST9+ 8/16 bit microcontroller
    EM_ST7 = 68,         // STMicroelectronics ST7 8-bit microcontroller
    EM_68HC16 = 69,      // Motorola MC68HC16 Microcontroller
    EM_68HC11 = 70,      // Motorola MC68HC11 Microcontroller
    EM_68HC08 = 71,      // Motorola MC68HC08 Microcontroller
    EM_68HC05 = 72,      // Motorola MC68HC05 Microcontroller
    EM_SVX = 73,         // Silicon Graphics SVx
    EM_ST19 = 75,        // Digital VAX
    EM_CRIS = 76,        // Axis Communications 32-bit embedded processor
    EM_JAVELIN = 77,     // Infineon Technologies 32-bit embedded processor
    EM_FIREPATH = 78,    // Element 14 64-bit DSP Processor
    EM_ZSP = 79,         // LSI Logic 16-bit DSP Processor
    EM_MMIX = 80,        // Donald Knuth's educational 64-bit processor
    EM_HUANY = 81,       // Harvard University machine-independent object files
    EM_PRISM = 82,       // SiTera Prism
    EM_AVR = 83,         // Atmel AVR 8-bit microcontroller
    EM_FR30 = 84,        // Fujitsu FR30
    EM_D10V = 85,        // Mitsubishi D10V
    EM_D30V = 86,        // Mitsubishi D30V
    EM_V850 = 87,        // NEC v850
    EM_M32R = 88,        // Mitsubishi M32R
    EM_MN10300 = 89,     // Matsushita MN10300
    EM_MN10200 = 90,     // Matsushita MN10200
    EM_PJ = 91,          // picoJava
    EM_OPENRISC = 92,    // OpenRISC 32-bit embedded processor
    EM_ARC_A5 = 93,      // ARC Cores Tangent-A5
    EM_XTENSA = 94,      // Tensilica Xtensa Architecture
    EM_VIDEOCORE = 95,   // Alphamosaic VideoCore processor
    EM_TMM_GPP = 96,     // Thompson Multimedia General Purpose Processor
    EM_NS32K = 97,       // National Semiconductor 32000 series
    EM_TPC = 98,         // Tenor Network TPC processor
    EM_SNP1K = 99,       // Trebia SNP 1000 processor
    EM_ST200 = 100,    // STMicroelectronics (www.st.com) ST200 microcontroller
    EM_IP2K = 101,     // Ubicom IP2xxx microcontroller family
    EM_MAX = 102,      // MAX Processor
    EM_CR = 103,       // National Semiconductor CompactRISC microprocessor
    EM_F2MC16 = 104,   // Fujitsu F2MC16
    EM_MSP430 = 105,   // Texas Instruments embedded microcontroller msp430
    EM_BLACKFIN = 106, // Analog Devices Blackfin (DSP) processor
    EM_SE_C33 = 107,   // S1C33 Family of Seiko Epson processors
    EM_SEP = 108,      // Sharp embedded microprocessor
    EM_ARCA = 109,     // Arca RISC Microprocessor
    EM_UNICORE = 110   // Microprocessor series from PKU-Unity Ltd. and MPRC of
                       // Peking University
  } e_machine_e;

  typedef enum { EV_NONE = 0, EV_CURRENT = 1 } e_version_e;

  // Program Header Types
  typedef enum {
    PT_NULL = 0,
    PT_LOAD = 1,
    PT_DYNAMIC = 2,
    PT_INERP = 3,
    PT_NOTE = 4,
    PT_SHLIB = 5,
    PT_PHDR = 6,
    PT_LOOS = 0x60000000,
    PT_HIOS = 0x6fffffff,
    PT_LOPROC = 0x70000000,
    PT_HIPROC = 0x7fffffff
  } p_type_e;

  typedef enum {
    PF_None = 0,
    PF_Exec = 1,
    PF_Write = 2,
    PF_Write_Exec = 3,
    PF_Read = 4,
    PF_Read_Exec = 5,
    PF_Read_Write = 6,
    PF_Read_Write_Exec = 7
  } p_flags_e;

  typedef enum {
    SHN_UNDEF = 0,          /* undefined, e.g. undefined symbol */
    SHN_LORESERVE = 0xff00, /* Lower bound of reserved indices */
    SHN_LOPROC = 0xff00,    /* Lower bound processor-specific index */
    SHN_HIPROC = 0xff1f,    /* Upper bound processor-specific index */
    SHN_LOOS = 0xff20,      /* Lower bound OS-specific index */
    SHN_HIOS = 0xff3f,      /* Upper bound OS-specific index */
    SHN_ABS = 0xfff1,       /* Absolute value, not relocated */
    SHN_COMMON = 0xfff2,    /* FORTRAN common or unallocated C */
    SHN_HIRESERVE = 0xffff  /* Upper bound of reserved indices */
  } s_name_e;

  typedef enum {
    SHT_NULL = 0,     /* Inactive section header */
    SHT_PROGBITS = 1, /* Information defined by the program */
    SHT_SYMTAB = 2,   /* Symbol table - not DLL */
    SHT_STRTAB = 3,   /* String table */
    SHT_RELA = 4,     /* Explicit addend relocations, Elf64_Rela */
    SHT_HASH = 5,     /* Symbol hash table */
    SHT_DYNAMIC = 6,  /* Information for dynamic linking */
    SHT_NOTE = 7,     /* A Note section */
    SHT_NOBITS = 8,   /* Like SHT_PROGBITS with no data */
    SHT_REL = 9,      /* Implicit addend relocations, Elf64_Rel */
    SHT_SHLIB = 10,   /* Currently unspecified semantics */
    SHT_DYNSYM = 11,  /* Symbol table for a DLL */

    SHT_LOOS = 0x60000000, /* Lowest OS-specific section type */
    SHT_HIOS = 0x6fffffff, /* Highest OS-specific section type */

    SHT_LOPROC = 0x70000000, /* Lowest processor-specific section type */
    SHT_HIPROC = 0x7fffffff  /* Highest processor-specific section type */
  } s_type_e;

  // *******Section Table********

  typedef enum {
    SF32_None = 0,
    SF32_Exec = 1,
    SF32_Alloc = 2,
    SF32_Alloc_Exec = 3,
    SF32_Write = 4,
    SF32_Write_Exec = 5,
    SF32_Write_Alloc = 6,
    SF32_Write_Alloc_Exec = 7
  } s_flags32_e;
  typedef enum {
    SF64_None = 0,
    SF64_Exec = 1,
    SF64_Alloc = 2,
    SF64_Alloc_Exec = 3,
    SF64_Write = 4,
    SF64_Write_Exec = 5,
    SF64_Write_Alloc = 6,
    SF64_Write_Alloc_Exec = 7
  } s_flags64_e;

  // ************ Symbol Table **************

  typedef enum {
    STB_LOCAL = 0,
    STB_GLOBAL = 1,
    STB_WEAK = 2,
    STB_OS_1 = 10,
    STB_OS_2 = 11,
    STB_OS_3 = 12,
    STB_PROC_1 = 13,
    STB_PROC_2 = 14,
    STB_PROC_3 = 15
  } sym_info_bind_e;

  typedef enum {
    STT_NOTYPE = 0,
    STT_OBJECT = 1,
    STT_FUNC = 2,
    STT_SECTION = 3,
    STT_FILE = 4,
    STT_OS_1 = 10,
    STT_OS_2 = 11,
    STT_OS_3 = 12,
    STT_PROC_1 = 13,
    STT_PROC_2 = 14,
    STT_PROC_3 = 15
  } sym_info_type_e;

  Q_ENUM(ei_class_2_e)
  Q_ENUM(ei_version_e)
  Q_ENUM(ei_osabi_e)
  Q_ENUM(ei_data_e)
  Q_ENUM(e_type_e)
  Q_ENUM(e_machine_e)
  Q_ENUM(e_version_e)
  Q_ENUM(p_type_e)
  Q_ENUM(p_flags_e)
  Q_ENUM(s_name_e)
  Q_ENUM(s_type_e)
  Q_ENUM(s_flags32_e)
  Q_ENUM(s_flags64_e)
  Q_ENUM(sym_info_bind_e)
  Q_ENUM(sym_info_type_e)
};

#endif // ELFHEADER_H
